package cn.dglydrpy.study.smartmvc.base.web;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import cn.dglydrpy.study.smartmvc.base.common.RequestHandler;
import cn.dglydrpy.study.smartmvc.base.common.HandlerMapping;
/**
 * 单一前端控制器
 * 负责接收请求，处理与HTTP协议有关逻辑
 * 同时处理 get 和 post请求
 * 为了增加广泛的实用性， 可以处理任何的*.do 请求
 * 将 请求URL设置为 *.do
 */
public class DispatherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	private HandlerMapping handlerMapping;//提供请求路径和处理器的请求关系
    
//	@Override
//	public void init() throws ServletException {
//		//在初始化里面读配置文件smartMVC.xml,实例化所有的controller之后存放于集合,
//		//然后将集合交给handlerMapping(反射读取处理器中的@RequestMapping).建立请求路径和处理器方法的对应关系
//		SAXReader reader = new SAXReader();
//		InputStream in = getClass().getClassLoader().getResourceAsStream("smartMVC.xml");
//		try {
//			Document doc = reader.read(in);
//			Element root = doc.getRootElement();
//			List<Element> eles = root.elements("bean");
//			
//			List beans = new ArrayList();
//			for (Element ele : eles) {
//				String className = ele.attributeValue("class");
//				Object bean = Class.forName(className).newInstance();
//				//将处理器实例放入集合
//				beans.add(bean);
//			}
//			//交给HandlerMapping来处理
//			handlerMapping = new HandlerMapping();
//			handlerMapping.execute(beans);
//			
//		} catch (Exception e) {
//			e.printStackTrace();
//			throw new ServletException(e);//重写的方法抛出的异常不能高于父类
//		}	 
//	}
	
	
//	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		/*
//		 * 请求-->前端控制器DispacherServlet-->HandlerMapper映射处理器-->控制器Controller-->视图模型对象ModelAndView-->视图处理器viewResolver
//		 */
//		request.setCharacterEncoding("utf-8");
//		String uri = request.getRequestURI();
//		//获得应用名
//		String contextPath = request.getContextPath();
//		//截取应用名之后的
//		String path = uri.substring(contextPath.length());
//		//根据请求路径找到对应的处理器
//		RequestHandler handler = handlerMapping.getHandler(path);
//		//调用处理器的方法
//		String viewName = null;
//		try {
//			//判断是否带参数
//			Method method = handler.getMethod();
//			Class[] types = method.getParameterTypes();
//			if (types.length>0) {
//				//带参数
//				Object[] params = new Object[types.length];
//				for(int i=0;i<types.length;i++){
//					if (types[i] ==HttpServletRequest.class) {
//						params[i] = request;
//					}
//					if (types[i] ==HttpServletResponse.class) {
//						params[i] = response;
//					}
//				}
//				viewName = method.invoke(handler.getController(),params).toString();
//			} else {//不带参数
//				viewName = method.invoke(handler.getController()).toString();
//			}
//			/*
//			 * 判断转发和重定向
//			 */
//			if(viewName.startsWith("redirect:")){//重定向
//				response.sendRedirect(request.getContextPath()+"/"+viewName.substring("redirect:".length()));
//				return;
//			}
//			//将视图名转换为对应的JSP
//			request.getRequestDispatcher("/WEB-INF/"+ viewName +".jsp").forward(request, response);
//		} catch (Exception e) {
//			e.printStackTrace();
//			throw new ServletException(e);
//		} 
//	}
	
	protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
		try {
			//从ServletContext获取已经创建并初始化完成的HandlerMapping对象，这样可以避免每次都初始化,可以提高软件的性能
			HandlerMapping mapping=(HandlerMapping) getServletContext().getAttribute("handlerMapping");
			//获取用户发起的请求
			String pth = request.getServletPath();
			System.out.println(pth); 
			//处理编码问题
			request.setCharacterEncoding("UTF-8");
			//执行 URL 路径对应的业务方法
			String target=mapping.execute(pth, request);
			//target代表需要显示是目标网页，
			//约定以 redirect:为前缀则进行重定向，如果控制器返回的字符串以 redirect: 为开头，则重定向到redirect: 以后的URL地址
			if(target.startsWith("redirect:")) {
				String path = target.substring(9);
				response.sendRedirect(path); 
			}else {
				String path = "/WEB-INF/jsp/"+target+".jsp";
				request.getRequestDispatcher(path).forward(request, response); 
			}
		}catch(Exception e) {
			e.printStackTrace();
			//抛出一个 ServletException，这个异常是作用是，将异常e抛给Web容器，Web容器会显示 500 错误页面到浏览器
			throw new ServletException(e);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
